package com.starhub.api.docarchive.service.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.starhub.api.docarchive.dao.DocArchiveBaseMapper;
import com.starhub.api.docarchive.dao.DocArchiveFollowMapper;
import com.starhub.api.docarchive.dto.DocArchiveBaseDTO;
import com.starhub.api.docarchive.entity.DocArchiveBase;
import com.starhub.api.docarchive.entity.DocArchiveFollow;
import com.starhub.api.docarchive.result.DocArchiveDealResult;
import com.starhub.api.docarchive.result.DocArchiveListResult;
import com.starhub.api.docarchive.service.DocArchiveService;
import com.starhub.api.docarchive.vo.DocArchiveBaseVO;
import com.starhub.common.security.util.SecurityUtils;
import com.starhub.common.sys.user.LoginUser;
import com.starhub.engine.generator.genid.IdGenerator;
import com.starhub.utils.Util;

import java.time.LocalDateTime;

/**   
 * 系统知识库管理服务层
 * @version: V1.0
 * @author: liuhf
 * @time 2025-05-18
 */
@Service
public class DocArchiveServiceImpl extends ServiceImpl<DocArchiveBaseMapper, DocArchiveBase> implements DocArchiveService {

    @Autowired
    private DocArchiveFollowMapper followMapper;

    @Autowired
    private DocArchiveBaseMapper baseMapper;

    /**
     * 获取共享知识库列表
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public DocArchiveListResult getSharedDocArchiveList(Integer pageNum, Integer pageSize) {
        // 分页
        Page<DocArchiveBase> page = new Page<>(pageNum, pageSize);
        // 查询条件
        LambdaQueryWrapper<DocArchiveBase> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocArchiveBase::getIsShared, 1);
        wrapper.eq(DocArchiveBase::getDeleteType, 0);
        wrapper.orderByDesc(DocArchiveBase::getCreateTime);
        // 查询总数
        Long total = this.count(wrapper);
        page.setTotal(total);
        // 查询分页数据
        Page<DocArchiveBase> recordPage = this.page(page, wrapper);

        // 转换
        Page<DocArchiveBaseVO> resultPage = new Page<>(pageNum, pageSize);
        BeanUtils.copyProperties(recordPage, resultPage, "records");
        resultPage.setRecords(recordPage.getRecords().stream()
                .map(this::convertToVo)
                .toList());
                
        return DocArchiveListResult.success(resultPage, total.intValue());
    }

    /**
     * 获取个人知识库列表
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public DocArchiveListResult getPersonalDocArchiveList(Integer pageNum, Integer pageSize) {
        LoginUser user = SecurityUtils.getCurrentUser();
        // 分页
        Page<DocArchiveBase> page = new Page<>(pageNum, pageSize);
        // 查询条件
        LambdaQueryWrapper<DocArchiveBase> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocArchiveBase::getUserId, user.getUserId());
        wrapper.eq(DocArchiveBase::getDeleteType, 0);
        wrapper.orderByDesc(DocArchiveBase::getCreateTime);
        // 查询总数
        Long total = this.count(wrapper);
        page.setTotal(total);
        // 查询分页数据
        Page<DocArchiveBase> recordPage = this.page(page, wrapper);

        Page<DocArchiveBaseVO> resultPage = new Page<>(pageNum, pageSize);
        BeanUtils.copyProperties(recordPage, resultPage, "records");
        resultPage.setRecords(recordPage.getRecords().stream()
                .map(this::convertToVo)
                .toList());
                
        return DocArchiveListResult.success(resultPage, total.intValue());
    }

    /**
     * 获取已关注的知识库列表
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public DocArchiveListResult getFollowedArchiveList(Integer pageNum, Integer pageSize) {
        LoginUser user = SecurityUtils.getCurrentUser();
        
        // 查询用户关注数据
        Page<DocArchiveBase> page = new Page<>(pageNum, pageSize);
        Page<DocArchiveBase> archivePage = followMapper.selectFollowedArchives(page, Util.getLongValue(user.getUserId()));
        
        // 转换为VO
        Page<DocArchiveBaseVO> resultPage = new Page<>(pageNum, pageSize);
        BeanUtils.copyProperties(archivePage, resultPage, "records");
        resultPage.setRecords(archivePage.getRecords().stream()
                .map(this::convertToVo)
                .toList());
                
        return DocArchiveListResult.success(resultPage, archivePage.getTotal());
    }
    
    /**
     * 分享/取消分享知识库
     * @param id
     * @param dealType 1:分享 0:取消分享
     * @return
     */
    @Override
    public DocArchiveDealResult checkShareDocArchive(Long id, int dealType) {
        DocArchiveDealResult result = checkDocArchive(id);
        if (!result.isSuccess()) {
            return result;
        }
        // 更新标识
        DocArchiveBase docArchive = new DocArchiveBase();
        docArchive.setId(id);
        docArchive.setIsShared(dealType);
        boolean success = this.updateById(docArchive);
        if (success) {
            return DocArchiveDealResult.success(id);
        } else {
            return DocArchiveDealResult.fail(dealType == 1 ? "分享失败" : "取消分享失败");
        }
    }

    /**
     * 获取知识库
     * @param id
     * @return
     */
    @Override
    public DocArchiveDealResult getDocArchiveById(long id) {
        // 获取知识库
        DocArchiveBase archive = this.getById(id);
        if (archive == null) {
            return DocArchiveDealResult.fail("知识库不存在");
        }
        
        // 检查是否已删除
        if (archive.getDeleteType() != null && archive.getDeleteType() == 1) {
            return DocArchiveDealResult.fail("知识库已被删除");
        }

        // 转换为VO
        DocArchiveBaseVO vo = convertToVo(archive);
        return DocArchiveDealResult.success(id, vo);
    }

    @Override
    public DocArchiveBaseVO getDataById(long id) {
        // 获取知识库
        DocArchiveBase archive = this.getById(id);
        if (archive == null) {
            return null;
        }
        return convertToVo(archive);
    }

    /**
     * 根据写作记录ID获取知识库
     * @param writingRecordId
     * @return
     */
    @Override
    public DocArchiveDealResult getDocArchiveByWritingRecordId(long writingRecordId) {
        // 构建查询条件
        LambdaQueryWrapper<DocArchiveBase> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocArchiveBase::getWritingRecordId, writingRecordId);
        wrapper.eq(DocArchiveBase::getDeleteType, 0);
        
        // 查询知识库
        DocArchiveBase archive = this.getOne(wrapper);
        if (archive == null) {
            return DocArchiveDealResult.fail("未找到对应的知识库");
        }

        // 转换为VO
        DocArchiveBaseVO vo = convertToVo(archive);
        return DocArchiveDealResult.success(archive.getId(), vo);
    }


    @Override
    public DocArchiveBaseVO getByWritingRecordId(long writingRecordId) {
        // 获取知识库
        LambdaQueryWrapper<DocArchiveBase> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocArchiveBase::getWritingRecordId, writingRecordId);
        wrapper.eq(DocArchiveBase::getDeleteType, 0);

        DocArchiveBase archive = this.getOne(wrapper);

        if (archive == null) {
            return null;
        }
        return convertToVo(archive);
    }

    /**
     * 新建知识库
     * @param dto
     * @return
     */
    @Override
    public DocArchiveDealResult createDocArchive(DocArchiveBaseDTO dto) {
        LoginUser user = SecurityUtils.getCurrentUser();
        Long id = IdGenerator.generateId();
        DocArchiveBase docarchive = new DocArchiveBase();
        BeanUtils.copyProperties(dto, docarchive);
        docarchive.setId(id);
        docarchive.setUserId(Util.getLongValue(user.getUserId()));
        docarchive.setIsShared(0);
        docarchive.setCreateTime(LocalDateTime.now());
        boolean success = this.save(docarchive);
        if (success) {
            return DocArchiveDealResult.success(id);
        } else {
            return DocArchiveDealResult.fail("新建失败");
        }
    }

    /**
     * 更新知识库
     * @param dto
     * @return
     */
    @Override
    public DocArchiveDealResult updateDocArchive(DocArchiveBaseDTO dto) {
        DocArchiveDealResult result = checkDocArchive(dto.getId());
        if (!result.isSuccess()) {
            return result;
        }

        // 更新内容时只更新content字段
        DocArchiveBase docarchive = new DocArchiveBase();
        docarchive.setContent(dto.getContent());
        docarchive.setId(dto.getId());
        boolean success = this.updateById(docarchive);
        if (success) {
            return DocArchiveDealResult.success(dto.getId());
        } else {
            return DocArchiveDealResult.fail("更新失败");
        }
    }

    @Override
    public DocArchiveDealResult deleteDocArchive(Long id) {
        DocArchiveDealResult result = checkDocArchive(id);
        if (!result.isSuccess()) {
            return result;
        }

        DocArchiveBase docarchive = new DocArchiveBase();
        docarchive.setId(id);
        docarchive.setDeleteType(1);
        boolean success = this.updateById(docarchive);
        if (success) {
            return DocArchiveDealResult.success(id);
        } else {
            return DocArchiveDealResult.fail("删除失败");
        }
    }

    /**
     * 检查知识库
     * @param id
     * @return
     */
    private DocArchiveDealResult checkDocArchive(Long id) {
        LoginUser user = SecurityUtils.getCurrentUser();
        DocArchiveBase existingDocArchive = this.getById(id);
        if (existingDocArchive == null) {
            return DocArchiveDealResult.fail("记录不存在");
        }
        if (!Util.null2String(existingDocArchive.getUserId()).equals(user.getUserId())) {
            return DocArchiveDealResult.fail("无权限操作该记录");
        }
        if (existingDocArchive.getDeleteType() != null && existingDocArchive.getDeleteType() == 1) {
            return DocArchiveDealResult.fail("记录已被删除");
        }
        return DocArchiveDealResult.success(id);
    }

    /**
     * 关注知识库
     * @param archiveId
     * @return
     */
    @Override
    public DocArchiveDealResult followArchive(Long archiveId) {
        LoginUser user = SecurityUtils.getCurrentUser();
        
        // 检查知识库是否存在
        DocArchiveBase archive = this.getById(archiveId);
        if (archive == null) {
            return DocArchiveDealResult.fail("知识库不存在");
        }
        
        // 检查是否已关注
        if (isFollowed(archiveId)) {
            return DocArchiveDealResult.fail("已经关注过该知识库");
        }

        // 创建关注关系
        DocArchiveFollow follow = new DocArchiveFollow();
        follow.setId(IdGenerator.generateId());
        follow.setUserId(Util.getLongValue(user.getUserId()));
        follow.setArchiveId(archiveId);
        follow.setCreateTime(LocalDateTime.now());
        
        boolean success = followMapper.insert(follow) > 0;
        if (success) {
            return DocArchiveDealResult.success(follow.getId());
        } else {
            return DocArchiveDealResult.fail("关注失败");
        }
    }

    /**
     * 取消关注知识库
     * @param archiveId
     * @return
     */
    @Override
    public DocArchiveDealResult unfollowArchive(Long archiveId) {
        LoginUser user = SecurityUtils.getCurrentUser();
        
        // 检查是否已关注
        if (!isFollowed(archiveId)) {
            return DocArchiveDealResult.fail("未关注该知识库");
        }

        // 删除关注关系
        LambdaQueryWrapper<DocArchiveFollow> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocArchiveFollow::getUserId, user.getUserId())
               .eq(DocArchiveFollow::getArchiveId, archiveId);
        
        boolean success = followMapper.delete(wrapper) > 0;
        if (success) {
            return DocArchiveDealResult.success(archiveId);
        } else {
            return DocArchiveDealResult.fail("取消关注失败");
        }
    }

    /**
     * 检查是否已关注
     * @param archiveId
     * @return
     */
    @Override
    public boolean isFollowed(Long archiveId) {
        LoginUser user = SecurityUtils.getCurrentUser();
        
        LambdaQueryWrapper<DocArchiveFollow> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocArchiveFollow::getUserId, user.getUserId())
               .eq(DocArchiveFollow::getArchiveId, archiveId);
        
        return followMapper.selectCount(wrapper) > 0;
    }


    /**
     * 转换为VO
     * @param docarchive
     * @return
     */
    private DocArchiveBaseVO convertToVo(DocArchiveBase docarchive) {
        DocArchiveBaseVO vo = new DocArchiveBaseVO();
        BeanUtils.copyProperties(docarchive, vo);
        vo.setId(docarchive.getId().toString());
        return vo;
    }
    
    @Override
    public DocArchiveListResult getSearchDocArchiveList(Integer pageNum, Integer pageSize,String keyWord,Integer type){
        LoginUser user = SecurityUtils.getCurrentUser();
        Page<DocArchiveBase> page = new Page<>(pageNum, pageSize);
        Page<DocArchiveBase> archivePage = null;
        if(type == 1){
            archivePage = baseMapper.selectSystemArchives(page, keyWord);
        }else if(type == 2){
            archivePage = baseMapper.selectPersonalArchives(page, keyWord, Util.getLongValue(user.getUserId()));
        }else if(type == 3){
            archivePage = baseMapper.selectFollowedArchives(page, keyWord);
        }
        // 转换为VO
        Page<DocArchiveBaseVO> resultPage = new Page<>(pageNum, pageSize);
        BeanUtils.copyProperties(archivePage, resultPage, "records");
        resultPage.setRecords(archivePage.getRecords().stream()
                .map(this::convertToVo)
                .toList());
                
        return DocArchiveListResult.success(resultPage, archivePage.getTotal());
    }
} 